<?php
require_once("constants.php");
require_once("pvc_templates.php");
class PVC_Project_Generator{


				// build an array to hold the constants
				private $dir_array = array();
				private $pvc_home;
				private $project_name;
				private $verbose;
				private $directories_to_create = array();
				private $smarty_class;

				/**
				 * Constructor
				 * @param project name
				 * @param set to true for verbose and false (default) for not verbose
				 */
				public function __construct($name, $verbose=false){
								$this->pvc_home = dirname(__FILE__).DIRECTORY_SEPARATOR."..";
								$this->project_home = $name.DIRECTORY_SEPARATOR;
								$this->verbose = $verbose;
								$this->project_name = $name;
								$this->smarty_class = ucfirst($name)."_Smarty";
								$this->build_dir_array();
								$this->create_dirs();
								$this->copy_libraries();
								$this->configure_views();
								$this->configure_routes();
								$this->configure_controllers();	
								$this->configure_main();						
				}
	
			/**
			 * Create the default controllers i.e root_controller and error_controller
			 */
			public function configure_controllers(){
				echo(" => creating default controllers\n");
				$root_controller = new PVC_Controller_Generator("root", $this->project_name, $this->verbose, true);
				$root_controller->generate();

				$error_controller = new PVC_Controller_Generator("error", $this->project_name, $this->verbose, true);
				$error_controller->generate();

			}

				/**
				 * Configure smarty by extending the class
				 */
				public function configure_views(){
					echo(" => configuring views\n");
					$smarty_file = strtolower($this->smarty_class).".class.php";
					if($this->verbose) { echo("    : writing $smarty_file\n"); }					
					$smarty_class_src  = $this->pvc_home.DIRECTORY_SEPARATOR.TEMPLATES.DIRECTORY_SEPARATOR.SMARTY_CLASS;
					$smarty_class_dest = $this->project_home.LIB.DIRECTORY_SEPARATOR.$smarty_file;
					$fp = fopen($smarty_class_src, "r");
					$fw = fopen($smarty_class_dest, "w");
					if($fp){
									$regex = "/^class !!!projectname!!!_Smarty extends Smarty {/";
									while(!feof($fp)) {
													$buffer = fgets($fp, 4096);
													if(preg_match($regex, $buffer)){
																	$class_string = "class ".ucfirst($this->project_name)."_Smarty extends Smarty {\n";
																	fwrite($fw, $class_string);
													} else {
														fwrite($fw, $buffer);
													}
									}
					}
					fclose($fp);
					fclose($fw);
			
					// Initial template
					if ($this->verbose) { echo("    : writing ". INDEX_TEMPLATE."\n"); }
					$root_template_src = $this->pvc_home.DIRECTORY_SEPARATOR.TEMPLATES.DIRECTORY_SEPARATOR.T_VIEWS.DIRECTORY_SEPARATOR.INDEX_TEMPLATE;
					$root_template_dist = $this->project_home.VIEWS.DIRECTORY_SEPARATOR.INDEX_TEMPLATE;
					copy($root_template_src, $root_template_dist);
				}

				public function configure_routes(){
					echo(" => creating default routes\n");
					$idx = get_index();
					$idx_file = fopen($this->project_home.PUB.DIRECTORY_SEPARATOR."index.php", "w");
					fwrite($idx_file, $idx);
				}

				public function configure_main(){
					echo(" => creating main class\n");
					$main = get_main($this->project_name);
					$main_file = fopen($this->project_home.LIB.DIRECTORY_SEPARATOR.strtolower($this->project_name).".class.php", "w");
					fwrite($main_file, $main);
				}

				/**
				 * Parse the directory array and create the directories
				 */
				public function create_dirs(){
								echo(" => creating directories\n");
								mkdir($this->project_name);
								foreach(array_keys($this->dir_array) as $d){
												if(is_array($this->dir_array[$d])){
																if($this->verbose) { echo("    : creating " . $this->project_name.DIRECTORY_SEPARATOR.$d."\n");}
																mkdir($this->project_name.DIRECTORY_SEPARATOR.$d);
																foreach($this->dir_array[$d] as $e){
																				if($this->verbose) { 
																								echo("    : creating " . $this->project_name.DIRECTORY_SEPARATOR.$d.DIRECTORY_SEPARATOR.$e."\n"); 
																				}
																				mkdir($this->project_name.DIRECTORY_SEPARATOR.$d.DIRECTORY_SEPARATOR.$e);
																}
												} else {
																if($this->verbose) {
																				echo("    : creating " . $this->project_name.DIRECTORY_SEPARATOR.$this->dir_array[$d] . "\n");
																}
																mkdir($this->project_name.DIRECTORY_SEPARATOR.$this->dir_array[$d]);
												}

								}
				}

				/**
				 * Copy relevent libraries to project directory
				 */
				public function copy_libraries(){
								echo(" => copying libraries\n");
								// Copy the smarty libraries
								$smarty_src = $this->pvc_home.DIRECTORY_SEPARATOR.INCLUDES.DIRECTORY_SEPARATOR."smarty";
								$smarty_dest = $this->project_home.DIRECTORY_SEPARATOR.LIB.DIRECTORY_SEPARATOR.SMARTY.DIRECTORY_SEPARATOR;
								// Copy the YAML libraries  
								$yaml_src = $this->pvc_home.DIRECTORY_SEPARATOR.INCLUDES.DIRECTORY_SEPARATOR.YAML;
								$yaml_dest = $this->project_home.DIRECTORY_SEPARATOR.LIB.DIRECTORY_SEPARATOR.YAML;
								// Copy the JQuery libraries
								$jq_src = $this->pvc_home.DIRECTORY_SEPARATOR.INCLUDES.DIRECTORY_SEPARATOR.JQUERY;
								$jq_dest = $this->project_home.DIRECTORY_SEPARATOR.PUB.DIRECTORY_SEPARATOR.JS.DIRECTORY_SEPARATOR.JQUERY;
								// Copy configuration files
							  $env_config_src = $this->pvc_home.DIRECTORY_SEPARATOR.TEMPLATES.DIRECTORY_SEPARATOR.T_CONFIG.DIRECTORY_SEPARATOR.ENV_CONFIG;
								$env_config_dest = $this->project_home.DIRECTORY_SEPARATOR.CONFIG.DIRECTORY_SEPARATOR.ENV_CONFIG;
								$prj_config_src = $this->pvc_home.DIRECTORY_SEPARATOR.TEMPLATES.DIRECTORY_SEPARATOR.T_CONFIG.DIRECTORY_SEPARATOR.PRJ_CONFIG;
								$prj_config_dest = $this->project_home.DIRECTORY_SEPARATOR.CONFIG.DIRECTORY_SEPARATOR.PRJ_CONFIG;
								$config_src = $this->pvc_home.DIRECTORY_SEPARATOR."libs".DIRECTORY_SEPARATOR.TEMPLATES.DIRECTORY_SEPARATOR.CONFIG_LIB;
								$config_dest = $this->project_home.DIRECTORY_SEPARATOR.LIB.DIRECTORY_SEPARATOR.CONFIG_LIB;

								echo("    : copying config class\n");
								copy($config_src, $config_dest);

								echo("    : copying smarty library\n");
								$this->copyr($smarty_src, $smarty_dest);
								echo("    : copying yaml library\n");
								copy($yaml_src, $yaml_dest);
								echo("    : copying jquery library \n");
								copy($jq_src, $jq_dest);
								echo(" => writing config files\n");
								if($this->verbose){echo("    : ".ENV_CONFIG."\n");}
								copy($env_config_src, $env_config_dest);
								// We have to do some replacements in project config
								if($this->verbose){echo("    : ".PRJ_CONFIG."\n");}
								$fp = fopen($prj_config_src, "r");
          			$fw = fopen($prj_config_dest, "w");
								if($fp){
												$regex = "/^\s*- name: !!name!!/";
												while(!feof($fp)) {
																$buffer = fgets($fp, 4096);
																if(preg_match($regex, $buffer)){
																	$string_to_write = "\t- name: {$this->project_name}\n";
																	fwrite($fw, $string_to_write);
																}else{
																	fwrite($fw, $buffer);
																}
												}
								}
								fclose($fp);
								fclose($fw);
				}





				/**
				 * Build an array to hold the directory structure
				 */
				private function build_dir_array(){
								$this->dir_array[] = LIB;
								$this->dir_array[VIEWS] = array(LAYOUTS); 
								$this->dir_array[] = APP;
								$this->dir_array[] = CONFIG;
								$this->dir_array[PUB] = array(JS,
																CSS,
																IMG );
				}

				
				/**
				 *
				 */
				public function __toString(){
								return " Project Name :: {$this->project_name}\n";
				}


				private function copyr($source, $dest){
								// Simple copy for a file
								if (is_file($source)) {
												$c = copy($source, $dest);
												chmod($dest, 0777);
												return $c;
								}

								// Make destination directory
								if (!is_dir($dest)) {
												$oldumask = umask(0);
												mkdir($dest, 0777);
												umask($oldumask);
								}

								// Loop through the folder
								$dir = dir($source);
								while (false !== $entry = $dir->read()) {
												// Skip pointers
												if ($entry == "." || $entry == "..") {
																continue;
												}

												// Deep copy directories
												if ($dest !== "$source/$entry") {
																$this->copyr("$source/$entry", "$dest/$entry");
												}
								}

								// Clean up
								$dir->close();
								return true;
				}



}

?>
